using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using IGGCore;
using IGG.Formatters;
using IGG.Data;

namespace IGG
{
    public class ModeDetailedStandingsFormatter : IModeFormatter
    {
        #region IModeFormatter Members

        private Random rnd = new Random();
        private StatManager statManager = new StatManager();

        private string GetFormattedStat(Dictionary<string, object> raw, string key)
        {
            string result = ToolBox.GetFormattedStringPadRight(raw["Tm"].ToString(), 4);
            result += ToolBox.GetFormattedStringPadRight(raw["Player"].ToString(), 20);
            result += ToolBox.GetFormattedStringPadRight(raw[key].ToString(), 8);
            return result;
        }

        private void FormatDivision(string divName, List<StandingTeam> teams, Scoreboard board)
        {
            SortedStat[] stats = statManager.GetRandomPairStats(board);
            IEnumerator<Dictionary<string, object>> enumSortedNL = stats[0].SortedList.GetEnumerator();
            IEnumerator<Dictionary<string, object>> enumSortedAL = stats[1].SortedList.GetEnumerator();

            SortedStat mlbStat = statManager.GetRandomMLBStat(board);
            IEnumerator<Dictionary<string, object>> enumSortedMLB = mlbStat.SortedList.GetEnumerator();

            FormatAdvancedStandingsHeader(divName, stats[0].Label.ToUpper(), stats[1].Label.ToUpper(), mlbStat.Label.ToUpper());
            for (int i = 0; i < 5; i++)
            {
                enumSortedNL.MoveNext();
                enumSortedAL.MoveNext();
                enumSortedMLB.MoveNext();
                FormatCombinedAdvancedStandingsLine(teams[i], false, GetFormattedStat(enumSortedNL.Current, stats[0].Key), GetFormattedStat(enumSortedAL.Current, stats[1].Key), GetFormattedStat(enumSortedMLB.Current, mlbStat.Key));
            }
        }

        public void FormatCombinedSpringTraining(Scoreboard board)
        {
            Output.WriteLine(ToolBox.GetFormattedStringPadRight(" Cactus League", 45) + "Grapefruit League");
            Output.WriteLine();
            for (int i = 0; i < 15; i++)
            {
                Output.Write(" ");
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsCactus[i].team, 17));
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsCactus[i].w.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsCactus[i].l.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsCactus[i].pct, 19));
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsGrapefruit[i].team, 17));
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsGrapefruit[i].w.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsGrapefruit[i].l.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(board.StandingsGrapefruit[i].pct, 19));
                Output.WriteLine();
            }
        }

        public void FormatCombinedMode(Scoreboard board)
        {
            if (board.StandingsALW != null && board.StandingsALW.Count > 0) // REGULAR SEASON
            {
                FormatDivision("NL EAST", board.StandingsNLE, board);
                Output.WriteLine();
                FormatDivision("NL CENTRAL", board.StandingsNLC, board);
                Output.WriteLine();
                FormatDivision("NL WEST", board.StandingsNLW, board);
                Output.WriteLine();
                FormatDivision("AL EAST", board.StandingsALE, board);
                Output.WriteLine();
                FormatDivision("AL CENTRAL", board.StandingsALC, board);
                Output.WriteLine();
                FormatDivision("AL WEST", board.StandingsALW, board);
                Output.WriteLine();

                if (board.StandingsNLWC != null && board.StandingsNLWC.Count > 0)
                {
                    Output.WriteLine();
                    SortedStat[] stats = statManager.GetRandomPairStats(board);
                    IEnumerator<Dictionary<string, object>> enumSortedNL = stats[0].SortedList.GetEnumerator();
                    IEnumerator<Dictionary<string, object>> enumSortedAL = stats[1].SortedList.GetEnumerator();

                    SortedStat mlbStat = statManager.GetRandomMLBStat(board);
                    IEnumerator<Dictionary<string, object>> enumSortedMLB = mlbStat.SortedList.GetEnumerator();

                    FormatAdvancedStandingsHeader("NL WILD CARD", stats[0].Label.ToUpper(), stats[1].Label.ToUpper(), mlbStat.Label.ToUpper());

                    enumSortedNL.MoveNext(); enumSortedAL.MoveNext(); enumSortedMLB.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsNLWC[0], true, GetFormattedStat(enumSortedNL.Current, stats[0].Key), GetFormattedStat(enumSortedAL.Current, stats[1].Key), GetFormattedStat(enumSortedMLB.Current, mlbStat.Key));

                    enumSortedNL.MoveNext(); enumSortedAL.MoveNext(); enumSortedMLB.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsNLWC[1], true, GetFormattedStat(enumSortedNL.Current, stats[0].Key), GetFormattedStat(enumSortedAL.Current, stats[1].Key), GetFormattedStat(enumSortedMLB.Current, mlbStat.Key));

                    enumSortedNL.MoveNext(); enumSortedAL.MoveNext(); enumSortedMLB.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsNLWC[2], true, GetFormattedStat(enumSortedNL.Current, stats[0].Key), GetFormattedStat(enumSortedAL.Current, stats[1].Key), GetFormattedStat(enumSortedMLB.Current, mlbStat.Key));

                    enumSortedNL.MoveNext(); enumSortedAL.MoveNext(); enumSortedMLB.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsNLWC[3], true, GetFormattedStat(enumSortedNL.Current, stats[0].Key), GetFormattedStat(enumSortedAL.Current, stats[1].Key), GetFormattedStat(enumSortedMLB.Current, mlbStat.Key));

                    enumSortedNL.MoveNext(); enumSortedAL.MoveNext(); enumSortedMLB.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsNLWC[4], true, GetFormattedStat(enumSortedNL.Current, stats[0].Key), GetFormattedStat(enumSortedAL.Current, stats[1].Key), GetFormattedStat(enumSortedMLB.Current, mlbStat.Key));

                    Output.WriteLine();
                    SortedStat[] stats2 = statManager.GetRandomPairStats(board);
                    IEnumerator<Dictionary<string, object>> enumSortedNL2 = stats2[0].SortedList.GetEnumerator();
                    IEnumerator<Dictionary<string, object>> enumSortedAL2 = stats2[1].SortedList.GetEnumerator();

                    SortedStat mlbStat2 = statManager.GetRandomMLBStat(board);
                    IEnumerator<Dictionary<string, object>> enumSortedMLB2 = mlbStat2.SortedList.GetEnumerator();

                    FormatAdvancedStandingsHeader("AL WILD CARD", stats2[0].Label.ToUpper(), stats2[1].Label.ToUpper(), mlbStat2.Label.ToUpper());

                    enumSortedNL2.MoveNext(); enumSortedAL2.MoveNext(); enumSortedMLB2.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsALWC[0], false, GetFormattedStat(enumSortedNL2.Current, stats2[0].Key), GetFormattedStat(enumSortedAL2.Current, stats2[1].Key), GetFormattedStat(enumSortedMLB2.Current, mlbStat2.Key));

                    enumSortedNL2.MoveNext(); enumSortedAL2.MoveNext(); enumSortedMLB2.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsALWC[1], false, GetFormattedStat(enumSortedNL2.Current, stats2[0].Key), GetFormattedStat(enumSortedAL2.Current, stats2[1].Key), GetFormattedStat(enumSortedMLB2.Current, mlbStat2.Key));

                    enumSortedNL2.MoveNext(); enumSortedAL2.MoveNext(); enumSortedMLB2.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsALWC[2], false, GetFormattedStat(enumSortedNL2.Current, stats2[0].Key), GetFormattedStat(enumSortedAL2.Current, stats2[1].Key), GetFormattedStat(enumSortedMLB2.Current, mlbStat2.Key));

                    enumSortedNL2.MoveNext(); enumSortedAL2.MoveNext(); enumSortedMLB2.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsALWC[3], false, GetFormattedStat(enumSortedNL2.Current, stats2[0].Key), GetFormattedStat(enumSortedAL2.Current, stats2[1].Key), GetFormattedStat(enumSortedMLB2.Current, mlbStat2.Key));

                    enumSortedNL2.MoveNext(); enumSortedAL2.MoveNext(); enumSortedMLB2.MoveNext();
                    FormatWCStandingsLine(board, board.StandingsALWC[4], false, GetFormattedStat(enumSortedNL2.Current, stats2[0].Key), GetFormattedStat(enumSortedAL2.Current, stats2[1].Key), GetFormattedStat(enumSortedMLB2.Current, mlbStat2.Key));
                    Output.WriteLine();
                }

            }
            else // SPRING TRAINING
            {
                Output.WriteLine();
                Output.WriteLine(" Cactus League");
                for (int i = 0; i < 15; i++)
                {
                    FormatAdvancedStandingsLine(board.StandingsCactus[i], true);
                }
                Output.WriteLine();
            }
        }

        public void FormatMode(Scoreboard board)
        {
            if (board.StandingsALW != null && board.StandingsALW.Count > 0) // REGULAR SEASON
            {
                FormatAdvancedStandingsHeader("NL EAST");
                FormatAdvancedStandingsLine(board.StandingsNLE[0]);
                FormatAdvancedStandingsLine(board.StandingsNLE[1]);
                FormatAdvancedStandingsLine(board.StandingsNLE[2]);
                FormatAdvancedStandingsLine(board.StandingsNLE[3]);
                FormatAdvancedStandingsLine(board.StandingsNLE[4]);
                Output.WriteLine();
                FormatAdvancedStandingsHeader("NL CENTRAL");
                FormatAdvancedStandingsLine(board.StandingsNLC[0]);
                FormatAdvancedStandingsLine(board.StandingsNLC[1]);
                FormatAdvancedStandingsLine(board.StandingsNLC[2]);
                FormatAdvancedStandingsLine(board.StandingsNLC[3]);
                FormatAdvancedStandingsLine(board.StandingsNLC[4]);
                Output.WriteLine();
                FormatAdvancedStandingsHeader("NL WEST");
                FormatAdvancedStandingsLine(board.StandingsNLW[0]);
                FormatAdvancedStandingsLine(board.StandingsNLW[1]);
                FormatAdvancedStandingsLine(board.StandingsNLW[2]);
                FormatAdvancedStandingsLine(board.StandingsNLW[3]);
                FormatAdvancedStandingsLine(board.StandingsNLW[4]);
                Output.WriteLine();
                FormatAdvancedStandingsHeader("AL EAST");
                FormatAdvancedStandingsLine(board.StandingsALE[0]);
                FormatAdvancedStandingsLine(board.StandingsALE[1]);
                FormatAdvancedStandingsLine(board.StandingsALE[2]);
                FormatAdvancedStandingsLine(board.StandingsALE[3]);
                FormatAdvancedStandingsLine(board.StandingsALE[4]);
                Output.WriteLine();
                FormatAdvancedStandingsHeader("AL CENTRAL");
                FormatAdvancedStandingsLine(board.StandingsALC[0]);
                FormatAdvancedStandingsLine(board.StandingsALC[1]);
                FormatAdvancedStandingsLine(board.StandingsALC[2]);
                FormatAdvancedStandingsLine(board.StandingsALC[3]);
                FormatAdvancedStandingsLine(board.StandingsALC[4]);
                Output.WriteLine();
                FormatAdvancedStandingsHeader("AL WEST");
                FormatAdvancedStandingsLine(board.StandingsALW[0]);
                FormatAdvancedStandingsLine(board.StandingsALW[1]);
                FormatAdvancedStandingsLine(board.StandingsALW[2]);
                FormatAdvancedStandingsLine(board.StandingsALW[3]);
                FormatAdvancedStandingsLine(board.StandingsALW[4]);
                if (board.StandingsNLWC != null && board.StandingsNLWC.Count > 0)
                {
                    //Output.WriteLine();
                    //FormatAdvancedStandingsHeader("NL WILD CARD");
                    //FormatWCStandingsLine(board, board.StandingsNLWC[0], true);
                    //FormatWCStandingsLine(board, board.StandingsNLWC[1], true);
                    //FormatWCStandingsLine(board, board.StandingsNLWC[2], true);
                    //FormatWCStandingsLine(board, board.StandingsNLWC[3], true);
                    //FormatWCStandingsLine(board, board.StandingsNLWC[4], true);
                    //Output.WriteLine();
                    //FormatAdvancedStandingsHeader("AL WILD CARD");
                    //FormatWCStandingsLine(board, board.StandingsALWC[0], false);
                    //FormatWCStandingsLine(board, board.StandingsALWC[1], false);
                    //FormatWCStandingsLine(board, board.StandingsALWC[2], false);
                    //FormatWCStandingsLine(board, board.StandingsALWC[3], false);
                    //FormatWCStandingsLine(board, board.StandingsALWC[4], false);
                    Output.WriteLine();
                }

            }
            else // SPRING TRAINING
            {
                Output.WriteLine();
                Output.WriteLine(" Cactus League");
                for (int i = 0; i < 15; i++)
                {
                    FormatAdvancedStandingsLine(board.StandingsCactus[i], true);
                }
                Output.WriteLine();
            }

        }

        private void FormatAdvancedStandingsLine(StandingTeam team)
        {
            FormatAdvancedStandingsLine(team, false);
        }

        private void FormatWCStandingsLine(Scoreboard board, StandingTeam team, bool national, string stat1, string stat2, string stat3)
        {

            // find the team in standings
            StandingTeam foundTeam = null;

            if (national)
            {
                foreach (StandingTeam ateam in board.StandingsNLE)
                {
                    if (ateam.team == team.team)
                    {
                        foundTeam = ateam;
                        break;
                    }
                }
                if (foundTeam == null)
                {
                    foreach (StandingTeam ateam in board.StandingsNLC)
                    {
                        if (ateam.team == team.team)
                        {
                            foundTeam = ateam;
                            break;
                        }
                    }
                }
                if (foundTeam == null)
                {
                    foreach (StandingTeam ateam in board.StandingsNLW)
                    {
                        if (ateam.team == team.team)
                        {
                            foundTeam = ateam;
                            break;
                        }
                    }
                }
            }
            else
            {
                foreach (StandingTeam ateam in board.StandingsALE)
                {
                    if (ateam.team == team.team)
                    {
                        foundTeam = ateam;
                        break;
                    }
                }
                if (foundTeam == null)
                {
                    foreach (StandingTeam ateam in board.StandingsALC)
                    {
                        if (ateam.team == team.team)
                        {
                            foundTeam = ateam;
                            break;
                        }
                    }
                }
                if (foundTeam == null)
                {
                    foreach (StandingTeam ateam in board.StandingsALW)
                    {
                        if (ateam.team == team.team)
                        {
                            foundTeam = ateam;
                            break;
                        }
                    }
                }
            }


            Output.Write(" ");
            Output.Write(ToolBox.GetFormattedStringPadRight(team.team, 15));
            Output.Write(ToolBox.GetFormattedStringPadRight(team.w.ToString(), 4));
            Output.Write(ToolBox.GetFormattedStringPadRight(team.l.ToString(), 4));
            Output.Write(ToolBox.GetFormattedStringPadRight(team.gb, 5));
            Output.Write(ToolBox.GetFormattedStringPadRight(foundTeam.last10, 7));
            Output.Write(ToolBox.GetFormattedStringPadRight(foundTeam.strk, 14));

            Output.Write(stat1.PadRight(32));
            Output.Write(stat2.PadRight(40));
            Output.Write(stat3);
            Output.WriteLine();
        }

        private void FormatAdvancedStandingsLine(StandingTeam team, bool spring)
        {
            if (spring)
            {
                Output.Write(" ");
                Output.Write(ToolBox.GetFormattedStringPadRight(team.team, 15));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.w.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.l.ToString(), 4));
                Output.Write(team.pct);
                Output.WriteLine();
            }
            else
            {
                Output.Write(" ");
                Output.Write(ToolBox.GetFormattedStringPadRight(team.team, 15));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.w.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.l.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.gb, 5));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.last10, 7));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.strk, 8));
                Output.WriteLine();
            }
        }

        private void FormatCombinedAdvancedStandingsLine(StandingTeam team, bool spring, string stat1, string stat2, string stat3)
        {
            if (spring)
            {
                Output.Write(" ");
                Output.Write(ToolBox.GetFormattedStringPadRight(team.team, 15));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.w.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.l.ToString(), 4));
                Output.Write(team.pct);
                Output.WriteLine();
            }
            else
            {
                Output.Write(" ");
                Output.Write(ToolBox.GetFormattedStringPadRight(team.team, 15));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.w.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.l.ToString(), 4));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.gb, 5));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.last10, 7));
                Output.Write(ToolBox.GetFormattedStringPadRight(team.strk, 14));
                Output.Write(stat1.PadRight(32));
                Output.Write(stat2.PadRight(40));
                Output.Write(stat3);
                Output.WriteLine();
            }
        }

        private void FormatAdvancedStandingsHeader(string division)
        {
            Output.WriteLine(" " + ToolBox.GetFormattedStringPadRight(division, 14)
                + " W   L   GB   L10   STRK");
        }

        private void FormatAdvancedStandingsHeader(string division, string statlabel1, string statlabel2, string mlbStatLabel)
        {
            Output.WriteLine(" " + ToolBox.GetFormattedStringPadRight(division, 14)
                + " W   L   GB   L10   STRK" + "           " + statlabel1.PadRight(32) + statlabel2.PadRight(40) + mlbStatLabel);

        }

        #endregion
    }
}
